# encoding=utf8
import sys
import datetime
import os
import subprocess
from flask import Flask, render_template, request, redirect, url_for, json, jsonify
from flask_cors import CORS
from modes import db, Hosts, projects, DeployTask, Node
from gitclone import git
# from repo import GitRepository
from utils import Codezip
from sqlalchemy import or_, and_
from sshclient import SSHProxy

# sys.setdefaultencoding('utf-8')
# reload(sys)

app = Flask(__name__)
db.init_app(app)
CORS(app)
app.config['SECRET_KEY'] = os.urandom(24)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:123456@127.0.0.1:3306/smartssh'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True


@app.route('/')
def hello_world():
    db.create_all()
    return render_template('server.html')


@app.route('/list')
def list():
    hostlist = Hosts.query.all()
    print(hostlist)
    return render_template('server.html', hostlist=hostlist)


@app.route('/status/<int:id>', methods=['GET', 'POST'])
def status(id):
    if request.method == "GET":
        taskstatus = DeployTask.query.filter_by(id=id).first()  # 找到发布信息
        uid = taskstatus.uid
        nodeinfo = Node.query.filter_by(task=uid).all()
        statulist = []
        for row in nodeinfo:
            nostatus = {'key': row.id, 'text': row.text, "parent": row.parent, 'color': row.status}
            statulist.append(nostatus)
        return jsonify(statulist)
    else:
        taskstatus = DeployTask.query.filter_by(id=id).first()  # 找到发布信息
        return json.dumps({'code': 'init', 'data': status})


@app.route('/add', methods=['GET', 'POST'])
def add():
    if request.method == 'GET':
        return render_template('addserver.html')
    else:
        dic1 = request.form
        savehosts(dic1)
        return redirect(url_for('list'))


@app.route('/project', methods=['GET', 'POST'])
def project():
    if request.method == 'GET':
        pallroject = projects.query.all()
        return render_template('project.html', pallroject=pallroject)
    else:
        dic2 = request.form
        project(dic2)
        return redirect(url_for('project'))


# 根据ID号获取项目的信息
@app.route('/task/<int:id>', methods=['GET', 'POST'])
def task(id):
    if request.method == 'GET':
        project = projects.query.filter_by(id=id).first()  # 根据项目ID拿到项目信息
        tasklist = DeployTask.query.filter_by(project=project.project).all()  # 拿到此项目的发布信息
        return render_template('tasklist.html', tasklist=tasklist, project=project)
    else:
        dic2 = request.form
        addproject(dic2)
        return redirect(url_for('project'))


# 添加发布任务
@app.route('/addtask/<int:id>', methods=['GET', 'POST'])
def addtask(id):
    if request.method == 'GET':
        projectinfo = projects.query.filter_by(id=id).first()
        return render_template('addtask.html', projectinfo=projectinfo)
    else:
        projectinfo = projects.query.filter_by(id=id).first()
        project = projectinfo.project
        env = projectinfo.env
        dic3 = request.form
        date = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
        uid = project + '-' + env + '-' + dic3['tag'] + '-' + date
        addtask(dic3, project, uid)
        return redirect(url_for('project'))


@app.route('/takeinfo/<int:id>', methods=['GET', 'POST'])
def takeinfo(id):
    if request.method == 'GET':
        taskinfo = DeployTask.query.filter_by(id=id).first()
        pro = taskinfo.project
        prinfo = projects.query.filter_by(project=pro).first()
        # git(prinfo.repo, taskinfo.tag)
        return render_template('run.html', taskinfo=taskinfo, prinfo=prinfo)


@app.route('/run/<int:id>', methods=['GET', 'POST'])
def run(id):
    if request.method == 'GET':
        taskinfo = DeployTask.query.filter_by(id=id).first()
        pro = taskinfo.project
        print(pro)
        prinfo = projects.query.filter_by(project=pro).first()  # 找到相对应的项目信息
        # start = Node(task=taskinfo.uid, key='start', text='开始', color='lightgray')
        # db.session.add(start)
        # db.session.commit()
        if prinfo.zip == "on":
            start = Node(task=taskinfo.uid, text='开始', status='green', )
            db.session.add(start)
            db.session.commit()
            try:
                Filepath = git(prinfo, taskinfo)  # 下载并获取下载文件打包的绝对地扯
                start = Node.query.filter_by(task=taskinfo.uid, text='开始').first()
                startdownload = Node(task=taskinfo.uid, text='下载', status='green', parent=start.id)
                db.session.add(startdownload)
                db.session.commit()

            except Exception as e:
                start = Node.query.filter_by(task=taskinfo.uid, text='开始').first()
                startdownload = Node(task=taskinfo.uid, text='下载', status='red', parent=start.id)
                db.session.add(startdownload)
                db.session.commit()

                # 开始查找信息准备上传文件
                taskinfo = DeployTask.query.filter_by(id=id).first()
                uid = taskinfo.uid
                allhost = projects.query.filter_by(project=taskinfo.project).first()
                date = datetime.datetime.now().strftime('%Y%m%d')
                serverpath = '/root/update/' + date + '/' + '%s' % taskinfo.uid
                unzippath = '/root/update/' + date + '/' + '%s' % taskinfo.uid
                updatefile = serverpath + '/' + taskinfo.uid + '.zip'  # 上传文件的约绝对地扯
                serverslist = allhost.servers.split(",")
                for host in serverslist:
                    infohost = Hosts.query.filter_by(hostname=host).first()
                    try:
                        with SSHProxy(infohost.ipaddr, int(infohost.port), infohost.username, infohost.passwd) as ssh:
                            ssh.command('mkdir -p %s' % serverpath)  # 在服务器上创建文件夹
                            ssh.upload(Filepath, updatefile)  # 上传文件
                            info = ssh.command('unzip %s -d %s' % (updatefile, serverpath))  # 解压文件
                            if taskinfo.after_download:
                                try:
                                    after_download = ssh.command('sh %s' % serverpath + '/scripts/after_download.sh')
                                    print(after_download)
                                except Exception as e:
                                    print("fail")
                                    return "red"
            except Exception as e:
                start = Node.query.filter_by(task=taskinfo.uid, text='开始').first()
                startdownload = Node(task=taskinfo.uid, text='下载', status='red', parent=start.id)
                db.session.add(startdownload)
                db.session.commit()
                return "red"
        else:
            start = Node.query.filter_by(task=taskinfo.uid, text='开始').first()
            startdownload = Node(task=taskinfo.uid, text='下载', status='red', parent=start.id)
            db.session.add(startdownload)
            db.session.commit()
            # 开始查找信息准备上传文件
            taskinfo = DeployTask.query.filter_by(id=id).first()
            uid = taskinfo.uid
            allhost = projects.query.filter_by(project=taskinfo.project).first()
            date = datetime.datetime.now().strftime('%Y%m%d')
            serverpath = '/root/update/' + date + '/' + '%s' % taskinfo.uid
            unzippath = '/root/update/' + date + '/' + '%s' % taskinfo.uid
            updatefile = serverpath + '/' + taskinfo.uid + '.zip'  # 上传文件的约绝对地扯
            serverslist = allhost.servers.split(",")
            for host in serverslist:
                infohost = Hosts.query.filter_by(hostname=host).first()
                try:
                    with SSHProxy(infohost.ipaddr, int(infohost.port), infohost.username, infohost.passwd) as ssh:
                        ssh.command('mkdir -p %s' % serverpath)  # 在服务器上创建文件夹
                        ssh.upload(Filepath, updatefile)  # 上传文件
                        info = ssh.command('unzip %s -d %s' % (updatefile, serverpath))  # 解压文件
                        if taskinfo.after_download:
                            try:
                                after_download = ssh.command('sh %s' % serverpath + '/scripts/after_download.sh')
                                print(after_download)
                            except Exception as e:
                                print("fail")

                    else:
                        print("not exits")

            # download_node = Node.query.filter(and_(Node.text == '下载', Node.task == taskinfo.uid)).first()
            # download_node.color = "green"
            # db.session.commit()
            return "completedownload"
            # download_node = Node.query.filter(and_(Node.text == '下载', Node.task == taskinfo.uid)).first()
            # download_node.color = "red"
            # db.session.commit()
            return "lin_162"
        # else:
        #     try:
        #         git(prinfo, taskinfo)
        #         # startdownload = Node(task=taskinfo.uid, key='startdownload', text='下载', color='lightgray',
        #         #                     parent='start')
        #         # db.session.add(startdownload)
        #         return "green"
        #     except Exception as e:
        #         # download_node = Node.query.filter(and_(Node.text == '下载', Node.task == taskinfo.uid)).first()
        #         # download_node.color = "red"
        #         # db.session.commit()
        #         return "red"


@app.route('/addproject', methods=['GET', 'POST'])
def addproject():
    if request.method == 'GET':
        return render_template('addpro.html')
    else:
        dic2 = request.form
        project(dic2)
        return redirect(url_for('project'))


def savehosts(dic1):
    add1 = Hosts(hostname=dic1['hostname'], ipaddr=dic1['ipaddr'], Groups=dic1['group'], passwd=dic1['password'],
                 port=dic1['port'])
    db.session.add(add1)
    db.session.commit()


def addtask(dic3, project1):
    print("line 93 %s" % project1)
    addtask1 = DeployTask(uid='uid', project=dic3['project'], tag=dic3['tag'], versioninfo=dic3['desc'],
                          after_download=dic3['after_download_sc'], before_download=dic3['before_download_sc'],
                          before_deploy_sc=dic3['before_deploy_sc'], after_deploy_sc=dic3['after_deploy_sc'])
    db.session.add(addtask1)
    db.session.commit()


def project(dic2):
    add1 = projects(project=dic2['project'], repo=dic2['repo'], env=dic2['env'], servers=dic2['server'],
                    path=dic2['path'], zip=dic2['zip'])
    db.session.add(add1)
    db.session.commit()


def addtask(dic3, project, uid):
    print(dic3['after_download_sc'])
    addtask1 = DeployTask(uid=uid, tag=dic3['tag'], status="未开始", before_download=dic3['before_download_sc'],
                          after_download=dic3['after_download_sc'], before_deploy_sc=dic3['before_deploy_sc'],
                          after_deploy_sc=dic3['after_deploy_sc'], project=project, versioninfo=dic3['versioninfo'])
    db.session.add(addtask1)
    db.session.commit()


if __name__ == '__main__':
    app.run()
